/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.qiniu.util.Auth;
import lombok.extern.slf4j.Slf4j;
import org.apache.lucene.search.similarities.Lambda;
import org.springblade.core.mp.base.BaseEntity;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.admin.dto.TaskPlanPageQueryDTO;
import org.springblade.modules.admin.entity.*;
import org.springblade.modules.admin.service.*;
import org.springblade.modules.admin.mapper.MaintainTemplateContentMapper;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.modules.admin.vo.MaintainPartsTemplateAttributeDetailVO;
import org.springblade.modules.admin.vo.TemplateContentDetailVO;
import org.springblade.modules.admin.vo.TemplateContentPageVO;
import org.springblade.modules.system.entity.Dict;
import org.springblade.modules.system.service.IDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * 保养模板内容 服务实现类
 *
 * @author zcc
 * @since 2021-09-24
 */
@Service
@Slf4j
public class MaintainTemplateContentServiceImpl extends BaseServiceImpl<MaintainTemplateContentMapper, MaintainTemplateContent> implements MaintainTemplateContentService {

	@Autowired
	private MaintainContentGuideService contentGuideService;
	@Autowired
	private MaintainTemplateRelationService templateRelationService;
	@Autowired
	private MaintainPartsTemplateService maintainPartsTemplateService;
	@Autowired
	private MaintainTemplateContentScoreDimensionService templateContentScoreDimensionService;
	@Autowired
	private IMaintainPartsTemplateAttributeService maintainPartsTemplateAttributeService;
	@Autowired
	private IDictService dictService;

	@Override
	public IPage<TemplateContentPageVO> selectTemplateContentPage(TaskPlanPageQueryDTO pageQueryDTO, IPage<TemplateContentPageVO> page) {
		List<String> tenantIds = new ArrayList<>();
		tenantIds.add(AuthUtil.getTenantId());
		tenantIds.add(BladeConstant.ADMIN_TENANT_ID);
		pageQueryDTO.setCurrentTenantId(AuthUtil.getTenantId());
        return page.setRecords(baseMapper.selectTemplateContentPage(pageQueryDTO,tenantIds,page));
	}

	@Override
	public TemplateContentDetailVO selectTemplateContentDetail(Long id) {
		TemplateContentDetailVO templateContentDetailVO = baseMapper.selectTemplateContentDetail(id,AuthUtil.getTenantId());
		List<MaintainPartsTemplate> list = maintainPartsTemplateService.list(new LambdaQueryWrapper<MaintainPartsTemplate>()
			.eq(MaintainPartsTemplate::getTemplateId, id)
			.eq(BaseEntity::getIsDeleted, 0).eq(MaintainPartsTemplate::getTenantId,AuthUtil.getTenantId())
		);
		templateContentDetailVO.setPartsRelation(list);
		MaintainTemplateContentScoreDimension scoreDimension = templateContentScoreDimensionService.getOne(Wrappers.<MaintainTemplateContentScoreDimension>lambdaQuery()
			.eq(MaintainTemplateContentScoreDimension::getContentId,id).eq(MaintainTemplateContentScoreDimension::getTenantId,AuthUtil.getTenantId()));
		templateContentDetailVO.setScoreDimension(scoreDimension);
		List<MaintainPartsTemplateAttributeDetailVO> attributeListVO = maintainPartsTemplateAttributeService.listByTemplateId(id);
		templateContentDetailVO.setPartsTemplateRelation(attributeListVO);
		return templateContentDetailVO;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean saveTemplateContent(MaintainTemplateContent templateContent) {

		boolean b = this.save(templateContent);

		if(ObjectUtil.isNotEmpty(templateContent.getContentGuides())){
			List<MaintainContentGuide> contentGuides = templateContent.getContentGuides();
			contentGuides.forEach(e -> {
				e.setContentId(templateContent.getId());
			});
			boolean isSuccessSave = contentGuideService.saveBatch(contentGuides);
			b = b && isSuccessSave;
		}
		// 2023-10-30 新增 配件关联
		if(ObjectUtil.isNotEmpty(templateContent.getRelationPartsIds())){
			List<Long> relationPartsIds = templateContent.getRelationPartsIds();
			boolean isSaveRelation = saveRelation(templateContent.getId(), relationPartsIds);
			b = b && isSaveRelation;
		}
		// 2024-10-14 新增配件-属性关联关系
		Long id = templateContent.getId();
		if(Func.isNotEmpty(templateContent.getRelationParts())){
			List<MaintainPartsTemplateAttribute> existList = maintainPartsTemplateAttributeService.list(
				Wrappers.<MaintainPartsTemplateAttribute>lambdaQuery()
					.eq(MaintainPartsTemplateAttribute::getTemplateId, id)
					.eq(BaseEntity::getIsDeleted, 0)
			);
			if(Func.isNotEmpty(existList)){
				List<Long> existIds = existList.stream().map(BaseEntity::getId).collect(Collectors.toList());
				maintainPartsTemplateAttributeService.removeByIds(existIds);
			}
			// 批量插入 templateId
			templateContent.getRelationParts().forEach(e -> {
				e.setTemplateId(id);
			});
			maintainPartsTemplateAttributeService.saveBatch(templateContent.getRelationParts());
		}
		if(Func.isNotEmpty(templateContent.getScoreDimension())){
			templateContent.getScoreDimension().setContentId(templateContent.getId());
			templateContent.getScoreDimension().setTenantId(AuthUtil.getTenantId());
			templateContentScoreDimensionService.save(templateContent.getScoreDimension());
		}
		return b;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean updateTemplateContent(Long id, MaintainTemplateContent templateContent) {
		templateContent.setId(id);
		this.updateById(templateContent);
		// 2024-10-14 新增配件-属性关联关系
		if(Func.isNotEmpty(templateContent.getRelationParts())){
			List<MaintainPartsTemplateAttribute> existList = maintainPartsTemplateAttributeService.list(
				Wrappers.<MaintainPartsTemplateAttribute>lambdaQuery()
					.eq(MaintainPartsTemplateAttribute::getTemplateId, id)
					.eq(BaseEntity::getIsDeleted, 0)
			);
			if(Func.isNotEmpty(existList)){
				List<Long> existIds = existList.stream().map(BaseEntity::getId).collect(Collectors.toList());
				maintainPartsTemplateAttributeService.removeByIds(existIds);
			}
			// 批量插入 templateId
			templateContent.getRelationParts().forEach(e -> {
				e.setTemplateId(id);
			});
			maintainPartsTemplateAttributeService.saveBatch(templateContent.getRelationParts());
		}
		contentGuideService.remove(Wrappers.<MaintainContentGuide>lambdaQuery().eq(MaintainContentGuide::getContentId,id));
		if(ObjectUtil.isNotEmpty(templateContent.getContentGuides())){
			List<MaintainContentGuide> contentGuides = templateContent.getContentGuides();
			contentGuides.forEach(e -> {
				e.setContentId(templateContent.getId());
				e.setTenantId(AuthUtil.getTenantId());
			});
			contentGuideService.saveBatch(contentGuides);
		}

		List<MaintainPartsTemplate> oldRelations = maintainPartsTemplateService.list(Wrappers.<MaintainPartsTemplate>lambdaQuery()
			.eq(BaseEntity::getIsDeleted, 0)
			.eq(MaintainPartsTemplate::getTemplateId, id)
			.eq(MaintainPartsTemplate::getTenantId,AuthUtil.getTenantId())
		);
		List<Long> collect = oldRelations.stream().map(BaseEntity::getId).collect(Collectors.toList());
		maintainPartsTemplateService.removeByIds(collect);
		if(ObjectUtil.isNotEmpty(templateContent.getRelationPartsIds())){
			// 新关联关系
			Boolean isSaveRelation = saveRelation(id, templateContent.getRelationPartsIds());
			log.info("新关联关系关联是否成功{}",isSaveRelation);
		}
		templateContentScoreDimensionService.remove(Wrappers.<MaintainTemplateContentScoreDimension>lambdaQuery().eq(MaintainTemplateContentScoreDimension::getContentId,id)
			.eq(MaintainTemplateContentScoreDimension::getTenantId,AuthUtil.getTenantId()));
		if(Func.isNotEmpty(templateContent.getScoreDimension())){
			templateContent.getScoreDimension().setContentId(templateContent.getId());
			templateContent.getScoreDimension().setTenantId(AuthUtil.getTenantId());
			templateContentScoreDimensionService.save(templateContent.getScoreDimension());
		}
		return Boolean.TRUE;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean copy(Long id) {

		MaintainTemplateContent oldTemplateContent = baseMapper.selectContentById(id);
		MaintainTemplateContent newTemplateContent = new MaintainTemplateContent();
		BeanUtil.copyProperties(oldTemplateContent,newTemplateContent, "id","tenantId","createTime","createUser","updateTime","updateUser","createDept","status","isDeleted");
		String newName = oldTemplateContent.getName()+"—复制"+ String.format("%04d",new Random().nextInt(9999));
		newTemplateContent.setName(newName);
		newTemplateContent.setTenantId(AuthUtil.getTenantId());
		this.save(newTemplateContent);

		List<MaintainContentGuide> oldTemplateContents = contentGuideService.list(Wrappers.<MaintainContentGuide>lambdaQuery().eq(MaintainContentGuide::getContentId,id));
		List<MaintainContentGuide> newTemplateContents = new ArrayList<>();
		oldTemplateContents.forEach(e -> {
			MaintainContentGuide contentGuide = new MaintainContentGuide();
			BeanUtil.copyProperties(e,contentGuide, "id","tenantId","createTime","createUser","updateTime","updateUser","createDept","status","isDeleted");
			contentGuide.setContentId(newTemplateContent.getId());
			contentGuide.setTenantId(AuthUtil.getTenantId());
			newTemplateContents.add(contentGuide);
		});
		contentGuideService.saveBatch(newTemplateContents);

		List<MaintainTemplateContentScoreDimension> oldScoreDimensions = templateContentScoreDimensionService.list(Wrappers.<MaintainTemplateContentScoreDimension>lambdaQuery()
			.eq(MaintainTemplateContentScoreDimension::getContentId,id).eq(MaintainTemplateContentScoreDimension::getTenantId,AuthUtil.getTenantId()));
		if(Func.isNotEmpty(oldScoreDimensions)){
			List<MaintainTemplateContentScoreDimension> newScoreDimensions = new ArrayList<>();
			oldScoreDimensions.forEach(e -> {
				MaintainTemplateContentScoreDimension scoreDimension = new MaintainTemplateContentScoreDimension();
				scoreDimension.setScoreDimensionId(e.getScoreDimensionId());
				scoreDimension.setContentId(newTemplateContent.getId());
				scoreDimension.setTenantId(AuthUtil.getTenantId());
				scoreDimension.setStatus(e.getStatus());
				newScoreDimensions.add(scoreDimension);
			});
			templateContentScoreDimensionService.saveBatch(newScoreDimensions);
		}
		return Boolean.TRUE;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean removeTemplateContent(List<Long> templateContentIds) {
		List<Long> templateIds = templateRelationService.list(Wrappers.<MaintainTemplateRelation>lambdaQuery().in(MaintainTemplateRelation::getContentId,templateContentIds))
			.stream().map(MaintainTemplateRelation::getTemplateId).collect(Collectors.toList());
		// 2023-10-30 新增 删除配件关联
		for (Long templateId : templateContentIds) {
			List<MaintainPartsTemplate> remoTargets = maintainPartsTemplateService.list(new LambdaQueryWrapper<MaintainPartsTemplate>()
				.eq(MaintainPartsTemplate::getTemplateId, templateId)
				.eq(BaseEntity::getIsDeleted, 0)
			);
			List<Long> collect = remoTargets.stream().map(BaseEntity::getId).collect(Collectors.toList());
			maintainPartsTemplateService.removeByIds(collect);
		}
		templateRelationService.remove(Wrappers.<MaintainTemplateRelation>lambdaQuery().in(MaintainTemplateRelation::getContentId,templateContentIds));
		templateIds.forEach(e -> {
			templateRelationService.updateTemplateWorkItemCount(e);
		});
		return super.removeByIds(templateContentIds);
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public Boolean copyBach(List<MaintainTemplateContent> contentList) {
		String randomNum = String.format("%04d",new Random().nextInt(9999));
		contentList.forEach(c -> {
			MaintainTemplateContent oldTemplateContent = baseMapper.selectContentById(c.getId());
			MaintainTemplateContent newTemplateContent = new MaintainTemplateContent();
			BeanUtil.copyProperties(oldTemplateContent,newTemplateContent, "id","tenantId","createTime","createUser","updateTime","updateUser","createDept","status","isDeleted");
			String newName = oldTemplateContent.getName()+"—复制"+ randomNum;
			newTemplateContent.setName(newName);
			newTemplateContent.setTenantId(AuthUtil.getTenantId());
			this.save(newTemplateContent);

			List<MaintainContentGuide> oldTemplateContents = contentGuideService.list(Wrappers.<MaintainContentGuide>lambdaQuery().eq(MaintainContentGuide::getContentId,c.getId()));
			List<MaintainContentGuide> newTemplateContents = new ArrayList<>();
			oldTemplateContents.forEach(e -> {
				MaintainContentGuide contentGuide = new MaintainContentGuide();
				BeanUtil.copyProperties(e,contentGuide, "id","tenantId","createTime","createUser","updateTime","updateUser","createDept","status","isDeleted");
				contentGuide.setContentId(newTemplateContent.getId());
				contentGuide.setTenantId(AuthUtil.getTenantId());
				newTemplateContents.add(contentGuide);
			});
			contentGuideService.saveBatch(newTemplateContents);

			List<MaintainTemplateContentScoreDimension> oldScoreDimensions = templateContentScoreDimensionService.list(Wrappers.<MaintainTemplateContentScoreDimension>lambdaQuery()
				.eq(MaintainTemplateContentScoreDimension::getContentId,c.getId()).eq(MaintainTemplateContentScoreDimension::getTenantId,AuthUtil.getTenantId()));
			if(Func.isNotEmpty(oldScoreDimensions)){
				List<MaintainTemplateContentScoreDimension> newScoreDimensions = new ArrayList<>();
				oldScoreDimensions.forEach(e -> {
					MaintainTemplateContentScoreDimension scoreDimension = new MaintainTemplateContentScoreDimension();
					scoreDimension.setScoreDimensionId(e.getScoreDimensionId());
					scoreDimension.setContentId(newTemplateContent.getId());
					scoreDimension.setTenantId(AuthUtil.getTenantId());
					scoreDimension.setStatus(e.getStatus());
					newScoreDimensions.add(scoreDimension);
				});
				templateContentScoreDimensionService.saveBatch(newScoreDimensions);
			}
		});
		return Boolean.TRUE;
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public Boolean updateBachScore(Integer partScore, List<Long> contentIds) {
		List<MaintainTemplateContentScoreDimension> result = new ArrayList<>();
		List<MaintainTemplateContentScoreDimension> scoreDimensions = templateContentScoreDimensionService.list(Wrappers.<MaintainTemplateContentScoreDimension>lambdaQuery()
			.eq(MaintainTemplateContentScoreDimension::getTenantId,AuthUtil.getTenantId()).in(MaintainTemplateContentScoreDimension::getContentId,contentIds));
		if(Func.isNotEmpty(scoreDimensions)){
			scoreDimensions.forEach(e -> {
				e.setStatus(partScore);
			});
			result.addAll(scoreDimensions);
			List<Long> oldContentIds = scoreDimensions.stream().map(MaintainTemplateContentScoreDimension::getContentId).collect(Collectors.toList());
			List<Long> nullContentIds = contentIds.stream().filter(e -> !oldContentIds.contains(e)).collect(Collectors.toList());
			if(Func.isNotEmpty(nullContentIds)){
				nullContentIds.forEach(e -> {
					MaintainTemplateContentScoreDimension scoreDimension = new MaintainTemplateContentScoreDimension();
					scoreDimension.setStatus(partScore);
					scoreDimension.setContentId(e);
					scoreDimension.setTenantId(AuthUtil.getTenantId());
					result.add(scoreDimension);
				});
			}
		}else {
			contentIds.forEach(e -> {
				MaintainTemplateContentScoreDimension scoreDimension = new MaintainTemplateContentScoreDimension();
				scoreDimension.setStatus(partScore);
				scoreDimension.setContentId(e);
				scoreDimension.setTenantId(AuthUtil.getTenantId());
				result.add(scoreDimension);
			});
		}
		return templateContentScoreDimensionService.saveOrUpdateBatch(result);
	}

	/**
	 * 共同行为抽取：工作项-结构赋值
	 * @param id 工作项id
	 * @param relationPartsIds 关联表配件id
	 * @return 是否成功
	 */
	private Boolean saveRelation(Long id, List<Long> relationPartsIds){
		List<MaintainPartsTemplate> templates = new ArrayList<>(10);
		for (Long relationPartsId : relationPartsIds) {
			MaintainPartsTemplate relation = new MaintainPartsTemplate();
			relation.setPartId(relationPartsId);
			relation.setTemplateId(id);
			relation.setTenantId(AuthUtil.getTenantId());
			templates.add(relation);
		}
		return maintainPartsTemplateService.saveBatch(templates);
	}

}










































